#pragma once
#include <iostream>
#include <time.h>
#include <string>
#include <stdarg.h>
#include <fstream>
// 日志时间 等级 内容 文件行号
// 类型不能作为参数传递
#define LEVELNUM 5
std::string logfile("./log/");

enum level
{
    NOTICE,
    WARNING,
    ERROR,
    FATAL,
    DEBUG
};

enum toFile
{
    SCREEN,
    ONEFILE,
    CLASSFILE
};

#define WHEREFILE SCREEN

class Log
{
public:
    Log()
    {
    }
    ~Log()
    {
    }

    void sendTo(const std::string &path, const std::string &info)
    {
        std::string pathName(logfile);
        pathName += path;
        std::ofstream out(pathName.c_str(), std::ios::app);
        out << info << std::endl;
    }

    void msgToFile(int file, int level, const std::string &info)
    {
        std::string wherefile("log.txt");
        switch (file)
        {
        case SCREEN:
            std::cout << info << std::endl;
            break;
        case ONEFILE:
            sendTo(wherefile, info);
            break;
        case CLASSFILE:
            wherefile+=".";
            wherefile+= levelStr[level];
            sendTo(wherefile, info);
            break;
        default:
            break;
        }
    }

    void operator()(int level, const char *format, ...)
    {
        time_t ct = time(nullptr);
        tm *lt = localtime(&ct);
        char leftbuffer[1024];
        snprintf(leftbuffer, sizeof(leftbuffer), "%s [%d-%d-%d %d:%d:%d] ", levelStr[level],
                 lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec);

        va_list s;
        va_start(s, format);
        char rightbuffer[1024];
        vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);
        va_end(s);
        std::string info(leftbuffer);
        info += rightbuffer;
        msgToFile(WHEREFILE, level, info);//默认输出到屏幕
    }

private:
    const char *levelStr[LEVELNUM] = {"Notice", "Warning", "Error", "Fatal", "Debug"};
};

Log lg;